namespace Dascoba.Umb.ProfileEditor
{
    using System;
    using System.Drawing;
    using System.IO;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;

    using AjaxControlToolkit;

    using umbraco.cms.businesslogic.member;
    using umbraco.cms.businesslogic.propertytype;
    using umbraco.editorControls;
    using umbraco.editorControls.ultimatepicker;

    /// <summary>
    /// ProfileEditor
    /// </summary>
    public partial class Editor : UserControl
    {
        #region Fields

        private static MemberType _currentMemberType;

        #endregion

        #region Methods

        /// <summary>
        /// Builds the profile editor.
        /// </summary>
        private void BuildProfileEditor()
        {
            _currentMemberType = MemberType.GetByAlias(Member.GetCurrentMember().ContentType.Alias);

            // Iterate through membertype tabs
            foreach (var tab in _currentMemberType.getVirtualTabs)
            {
                var tabPanel = new TabPanel {HeaderText = tab.Caption};

                this.TabContainer1.Tabs.Add(tabPanel);

                var propertyTable = new Table
                                    {
                                            BorderStyle = BorderStyle.None,
                                            BorderWidth = Unit.Pixel(0),
                                            Width = Unit.Percentage(100)
                                    };
                tabPanel.Controls.Add(propertyTable);

                // Iterate through properties on tab
                foreach (var propertyType in tab.PropertyTypes)
                {
                    // Check if property is allowed to be viewed
                    if (!_currentMemberType.ViewOnProfile(propertyType))
                        continue;

                    // Build the property GUI
                    var propertyLabel = new Label
                                        {ID = string.Format("lbl{0}", propertyType.Alias), Text = propertyType.Name};

                    // Table Row
                    var propertyRow = new TableRow();
                    propertyTable.Rows.Add(propertyRow);

                    // Row Cells
                    var labelCell = new TableCell {Width = Unit.Percentage(33)};
                    var propertyCell = new TableCell {Width = Unit.Percentage(66)};

                    propertyRow.Cells.Add(labelCell);
                    propertyRow.Cells.Add(propertyCell);

                    // Check for property background image
                    var imagePath = GetBackgroundPath(propertyType);
                    if (imagePath != string.Empty)
                    {
                        var bitmap = new Bitmap(HttpContext.Current.Server.MapPath(imagePath));
                        propertyCell.Height = Unit.Pixel(bitmap.Height);
                        propertyCell.Width = Unit.Pixel(bitmap.Width);
                        propertyCell.Style.Add("background", string.Format("url({0})", imagePath));
                    }

                    // Add Label and Property to cells
                    labelCell.Controls.Add(propertyLabel);
                    propertyCell.Controls.Add(this.GetPropertyPanel(propertyType));
                }
            }
            if (this.TabContainer1.Tabs.Count == 0)
                this.TabContainer1.Tabs.Add(new TabPanel
                                            {HeaderText = "There are no settings available for your profile"});
            this.TabContainer1.ActiveTabIndex = 0;
        }

        /// <summary>
        /// Gets the property panel.
        /// </summary>
        /// <param name="propertyType">Type of the property.</param>
        /// <returns></returns>
        private Panel GetPropertyPanel(PropertyType propertyType)
        {
            if (propertyType == null)
                return null;

            var propertyPanel = new Panel();
            var propertyValue = CurrentProfile.GetProperty(propertyType.Alias);

            try
            {
                var dataEditor = propertyType.DataTypeDefinition.DataType.DataEditor;
                var fullTypeName = dataEditor.GetType().ToString();

                switch (fullTypeName)
                {
                    case "umbraco.editorControls.textfield.TextFieldEditor":
                    case "umbraco.editorControls.textfieldmultiple.textfieldMultipleDataType":
                        {
                            var textField = new TextBox
                                            {
                                                    ID = string.Format("editor{0}", propertyType.Alias),
                                                    Text = Convert.ToString(propertyValue)
                                            };
                            textField.Text = (string) propertyValue;
                            textField.TextChanged += this.Editor_TextChanged;
                            textField.Enabled = _currentMemberType.MemberCanEdit(propertyType);
                            propertyPanel.Controls.Add(textField);
                        }
                        break;
                    case "umbraco.editorControls.numberfield":
                        {
                            var numberField = new TextBox
                                              {
                                                      ID = string.Format("editor{0}", propertyType.Alias),
                                                      Text = Convert.ToString(propertyValue)
                                              };
                            numberField.TextChanged += this.Editor_TextChanged;
                            numberField.Enabled = _currentMemberType.MemberCanEdit(propertyType);
                            propertyPanel.Controls.Add(numberField);
                        }
                        break;
                    case "umbraco.editorControls.yesNo":
                        {
                            var yesNo = new CheckBox
                                        {
                                                ID = string.Format("editor{0}", propertyType.Alias),
                                                Checked = Convert.ToBoolean(propertyValue)
                                        };
                            yesNo.CheckedChanged += this.Editor_CheckedChanged;
                            yesNo.Enabled = _currentMemberType.MemberCanEdit(propertyType);
                            propertyPanel.Controls.Add(yesNo);
                        }
                        break;
                    case "umbraco.editorControls.radiobox":
                        {
                            var radioBox = new RadioButtonList
                                           {
                                                   ID = string.Format("editor{0}", propertyType.Alias),
                                                   SelectedValue = Convert.ToString(propertyValue)
                                           };
                            radioBox.SelectedIndexChanged += this.Editor_SelectedIndexChanged;
                            propertyPanel.Controls.Add(radioBox);
                        }
                        break;
                    case "umbraco.editorControls.datefield":
                        {
                            var dateField = new TextBox
                                            {
                                                    ID = string.Format("editor{0}", propertyType.Alias),
                                                    Text = Convert.ToString(propertyValue)
                                            };
                            dateField.TextChanged += this.Editor_TextChanged;
                            dateField.Enabled = _currentMemberType.MemberCanEdit(propertyType);
                            var calendarExtender = new CalendarExtender {TargetControlID = dateField.ID};
                            propertyPanel.Controls.Add(dateField);
                            propertyPanel.Controls.Add(calendarExtender);
                        }
                        break;
                    case "umbraco.editorControls.dropdown":
                        {
                            var dropDown = (dropdown) dataEditor;

                            // Rebuild dropdown without 'Choose...' item
                            dropDown.ID = string.Format("editor{0}", propertyType.Alias);
                            dropDown.SelectedValue = Convert.ToString(propertyValue);
                            dropDown.SelectedIndexChanged += this.Editor_SelectedIndexChanged;
                            propertyPanel.Controls.Add(dropDown);
                        }
                        break;
                    case "umbraco.editorControls.tinymce.TinyMCE":
                    case "umbraco.editorControls.tinyMCE3.TinyMCE":
                    case "umbraco.editorControls.simpleEditor.SimpleEditor":
                        {
                            if (dataEditor.TreatAsRichTextEditor)
                            {
                                //TODO : Include RTF editor
                            }
                            else
                            {
                                var simpleEditor = new TextBox
                                                   {
                                                           ID = string.Format("editor{0}", propertyType.Alias),
                                                           Text = Convert.ToString(propertyValue),
                                                           TextMode = TextBoxMode.MultiLine,
                                                           Rows = 4
                                                   };
                                simpleEditor.TextChanged += this.Editor_TextChanged;
                                simpleEditor.Enabled = _currentMemberType.MemberCanEdit(propertyType);
                                propertyPanel.Controls.Add(simpleEditor);
                            }
                        }
                        break;
                    case "umbraco.editorControls.ultimatePicker.ultimatePickerDataEditor":
                        {
                            var picker = new DropDownList
                                         {
                                                 ID = string.Format("editor{0}", propertyType.Alias),
                                                 DataSource =
                                                         ((ListControl) (((ultimatePickerDataEditor) dataEditor).Editor)).Items,
                                         };
                            picker.DataBind();
                            picker.SelectedValue = Convert.ToString(propertyValue);
                            picker.SelectedIndexChanged += this.Editor_SelectedIndexChanged;
                            propertyPanel.Controls.Add(picker);
                        }
                        break;
                    default:
                        {
                            var label = new Label
                                        {
                                                ID = string.Format("editor{0}", propertyType.Alias),
                                                Text = Convert.ToString(propertyValue)
                                        };
                            propertyPanel.Controls.Add(label);
                        }
                        break;
                }
                return propertyPanel;
            }
            catch (Exception ex)
            {
                propertyPanel.Controls.Clear();
                propertyPanel.Controls.Add(new Literal
                                           {
                                                   Text =
                                                           string.Format(
                                                           "Message:{0}<p>Stack Trace: {1}</p>Value Type: {2}",
                                                           ex.Message,
                                                           ex.StackTrace,
                                                           propertyValue.GetType())
                                           });
                return propertyPanel;
            }
        }

        /// <summary>
        /// Gets the background path.
        /// </summary>
        /// <param name="propertyType">Type of the property.</param>
        /// <returns></returns>
        private static string GetBackgroundPath(PropertyType propertyType)
        {
            var clientPath = string.Format("/images/backgrounds/{0}.jpg", propertyType.Alias);
            var serverPath = HttpContext.Current.Server.MapPath(clientPath);
            return File.Exists(serverPath) ? clientPath : string.Empty;
        }

        #endregion

        #region Event Methods

        /// <summary>
        /// Handles the Load event of the Page.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
                this.BuildProfileEditor();
        }

        /// <summary>
        /// Handles the Init event of the TabContainer1 control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void TabContainer1_Init(object sender, EventArgs e)
        {
            if (IsPostBack)
            {
                // needed to repopulate the editor on a postback
                // when profile is updated
                this.BuildProfileEditor();
            }
        }

        /// <summary>
        /// Handles the Click event of the btnUpdate control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void btnUpdate_Click(object sender, EventArgs e)
        {
            this.litStatus.Text = CurrentProfile.Save() ? "Profile updated sucessfully!" : "Profile update failed!";
        }

        #region ... for textbox controls

        /// <summary>
        /// Handles the TextChanged event of the ProfileEditor control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void Editor_TextChanged(object sender, EventArgs e)
        {
            var alias = ((TextBox) sender).ID.Replace("editor", "");
            var value = ((TextBox) sender).Text;

            CurrentProfile.SetProperty(alias, value);
        }

        #endregion

        #region ... for radiobutton and checkbox controls

        /// <summary>
        /// Handles the CheckedChanged event of the ProfileEditor control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void Editor_CheckedChanged(object sender, EventArgs e)
        {
            var alias = ((CheckBox) sender).ID.Replace("editor", "");
            var value = ((CheckBox) sender).Checked;

            CurrentProfile.SetProperty(alias, value);
        }

        #endregion

        #region ... for listcontrols

        /// <summary>
        /// Handles the SelectedIndexChanged event of the ProfileEditor control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void Editor_SelectedIndexChanged(object sender, EventArgs e)
        {
            var alias = ((ListControl) sender).ID.Replace("editor", "");
            var value = ((ListControl) sender).SelectedItem.Value;

            CurrentProfile.SetProperty(alias, value);
        }

        #endregion

        #endregion
    }
}